package cn.tworice.generate.service;

import cn.tworice.common.util.file.FileUtils;
import cn.tworice.generate.config.GenerateProperties;
import cn.tworice.generate.constant.CodeGenConst;
import cn.tworice.generate.util.CodeUtils;
import cn.tworice.generate.vo.CodeVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * 代码生成
 *
 */
@Component
@Slf4j
public class VueGeneration{

    @Resource
    private CodeUtils codeUtils;

    @Resource
    private GenerateProperties generateProperties;


    /**
     * 构建Vue页面的内容
     *
     * @author 二饭[tworice@sina.cn][2022/1/12 0:19]
     */
    public boolean buildCodeVue(CodeVO codeVO) {
        String content = codeUtils.readByName(codeVO.getTemplateName());
        content = content.replace(CodeGenConst.PAGE_TABLE_ITEM, codeVO.getTableItem());
        content = content.replace(CodeGenConst.PAGE_FROM_ITEM, codeVO.getFormItem());
        content = content.replace(CodeGenConst.PAGE_FROM, codeVO.getForm());
        content = content.replace(CodeGenConst.PAGE_URL, codeVO.getUrl());
        content = content.replace(CodeGenConst.PAGE_RULES, codeVO.getRules());
        content = content.replace(CodeGenConst.PAGE_SEARCH_ITEM, codeVO.getSearchItem());
        content = content.replace(CodeGenConst.PAGE_SEARCH, codeVO.getSearch());
        content = content.replace(CodeGenConst.PAGE_DICT, codeVO.getDict());
        content = content.replace(CodeGenConst.PAGE_DICT_FUNCTION, codeVO.getInitDict());
        content = content.replace(CodeGenConst.PAGE_DICT_INIT, codeVO.getInitDicts());
        content = content.replace(CodeGenConst.PAGE_SHOW_INFO, codeVO.getShowInfo());


        String fileName = codeUtils.getVueProjectPath() + "\\src\\components\\code\\" + codeVO.getPageName() + ".vue";
        return codeUtils.createFile(fileName, content);
    }

    /**
     * 获取路由信息,返回路由数组
     * 不包含头部和尾部
     * @author 二饭[tworice@sina.cn]
     */
    public String getRouter() {
        String content = FileUtils.readFile(this.getRouterPath());
        content = content.substring(content.indexOf("//$start") + 8, content.lastIndexOf("//$end")).trim();
        return content;
    }

    /**
     * 添加路由信息
     *
     * @author 二饭[tworice@sina.cn][2022/1/12 0:15]
     */
    public boolean addRouter(int type, String path, String name) {
        log.info("添加路由信息");
        String router = null;

        if (type == 1) {
            // 添加模块路由
            router = addModuleToRouter(path, name);
        } else if (type == 2) {
            // 添加页面路由
            router = addPageToRouter(path, name);
        } else {
            return false;
        }
        return refreshRouter(router);
    }

    /**
     * 将路由器内容写入路由表中
     *
     * @param router 路由数组
     * @author 二饭[tworice@sina.cn][2022/1/11 23:47]
     */
    public boolean refreshRouter(String router) {
        log.info("将路由内容写入路由表中");
        try {
            if (router != null) {
                // 路由文件位置
                String file = getRouterPath();
                // 获取路由文件内容
                String fileContent = FileUtils.readFile(file);
                String content = fileContent.substring(0, fileContent.indexOf("//$start")) + "\r\n//$start\r\n" + router + "\r\n//$end\r\n";
                content += fileContent.substring(fileContent.indexOf("//$end") + 6);
                codeUtils.createFile(file, content);
            }
        } catch (Exception exception) {
            return false;
        }
        return true;
    }

    /**
     * 添加路由模块
     *
     * @param name 路由名称
     * @param path 路由跳转路径
     * @return 返回构建好的路由数组
     * @author 二饭[tworice@sina.cn][2022/1/11 23:25]
     */
    public String addModuleToRouter(String path, String name) {
        log.info("添加模块路由");
        String router = getRouter();
        String content = router.substring(0, router.lastIndexOf("]"));
        // 构建添加到路由的内容
        String buffer = "{path:'" +
                path +
                "',\n" +
                "name:'" +
                name +
                "',\n" +
                "component: ()=>import('@/components/index'),\n" +
                "children:[]},\n";
        content = content + buffer + "]";

        return content;
    }

    /**
     * 添加页面路由
     *
     * @author 二饭[tworice@sina.cn][2022/1/12 17:53]
     */
    public String addPageToRouter(String path, String name) {
        log.info("添加页面路由");
        String router = getRouter(); // 路由文件内容
        StringBuilder buffer = new StringBuilder();

        if (path == null || path.trim().isEmpty()) {
            return "";
        }

        // 1、判断要添加页面路由是几层
        String pathLevel = "";
        if ("/".equals(path.trim().charAt(0) + "")) {
            pathLevel = path.substring(1);
        }
        String[] split = pathLevel.split("/");

        // 2、根据路由路径找页面路由应该添加到哪个children下
        if (split.length == 1) {
            path = "/admin" + path;
        }

        // 从新增路由路径中获取模块路由的名称
        String module = path.substring(0, path.lastIndexOf("/"));
        int moduleIndex = router.indexOf("\""+module+"\""); // 模块名称所在文件内容索引
        buffer.append(router, 0, moduleIndex);

        // 获取从模块开始的内容
        String moduleContent = router.substring(moduleIndex);
        int childrenIndex = moduleContent.indexOf("children");
        buffer.append(moduleContent, 0, childrenIndex);
        buffer.append("children:");
        String childrenContent = moduleContent.substring(childrenIndex);
        String[] children = getBracketIndex('[', ']', childrenContent);
        if (children[0].length() == 2) {
            buffer.append(children[0], 0, children[0].length() - 1);
        } else {
            String substring = children[0].substring(0, children[0].length() - 2).trim();
            buffer.append(substring);
            /*如果该路由数组最后一个]前面的符号不是逗号或中括号 则在其后加一个逗号*/
            if (!substring.endsWith(",") && !substring.endsWith("[")) {
                buffer.append(",");
            }
        }
        // 截取路由path
        buffer.append("\n{path:'");
        buffer.append(path.substring(path.lastIndexOf("/") + 1));
        buffer.append("',");
        buffer.append("name:'");
        buffer.append(name);
        buffer.append("',");
        buffer.append("component: (resolve) =>require(['@/components/code/");
        buffer.append(path.substring(path.lastIndexOf("/") + 1));
        buffer.append(".vue',], resolve)},");
        buffer.append("]");
        buffer.append(children[1]);
        return buffer.toString();
    }

    /**
     * 传入开始和结束字符，返回开始和结束字符包含的内容
     *
     * @param beginBracket 开始字符
     * @param endBracket   结束字符
     * @param content      要查询的原始内容
     * @return 返回包含的内容，包括两个开始和结束字符
     * @author 二饭[tworice@sina.cn][2022/1/12 16:45]
     */
    public String[] getBracketIndex(char beginBracket, char endBracket, String content) {
        int number = 1;
        int beginIndex = content.indexOf(beginBracket);// 开始索引
        int endIndex = -1;// 结束索引

        for (int i = beginIndex + 1; i < content.length(); i++) {
            if (content.charAt(i) == beginBracket) {
                number++;
            } else if (content.charAt(i) == endBracket) {
                if (number - 1 == 0) {
                    endIndex = i;
                    break;
                } else {
                    number--;
                }
            }
        }

        String[] arr = new String[2];
        arr[0] = content.substring(beginIndex, endIndex + 1).trim(); // 路由数组内容[]包括的内容
        arr[1] = content.substring(endIndex + 1).trim();// []后面的内容
        return arr;
    }

    /**
     * 获取VueRouter路由文件路径
     * @return 文件绝对路径
     */
    private String getRouterPath() {
        return codeUtils.getVueProjectPath() + "\\src\\core\\router.js";
    }

}
